<template>
  <div v-loading="isLoading" class="panel-linkage">
    <div class="content">
      <div v-if="isShowRedisTip" style="margin-bottom: 8px;">
        <el-icon color="#409eff" size="16" style="vertical-align: middle;">
          <info-filled />
        </el-icon>
        <span>{{ $demoi18n('panel-linkage.redisTip') }}</span>
      </div>
      <div class="btns_line">
        <el-radio-group v-model="evtType" style="margin-bottom: 30px">
          <el-radio-button label="normal">{{ $demoi18n('panel-linkage.commonEvent') }}</el-radio-button>
          <el-radio-button v-if="isAdvancedVisible" label="advanced">{{
            $demoi18n('panel-linkage.advancedEvents')
          }}</el-radio-button>
          <el-radio-button v-if="isInitiativeVisible" label="initiative">{{
            $demoi18n('panel-linkage.activeTriggering')
          }}</el-radio-button>
        </el-radio-group>
      </div>

      <!-- 普通事件联动 -->
      <div v-show="evtType === 'normal'">
        <el-button
          v-if="canCompAddEvent"
          class="btn-sure btn-add"
          icon="CirclePlusFilled"
          size="default"
          @click="addEvent"
        >
          {{ $demoi18n('btn.add') }}
        </el-button>

        <!-- 发出事件设置 -->
        <div v-if="isDiyOutSetting">
          <!-- 动态添加参数 -->
          <LinkageParamsSetting
            v-if="fixedEvents.length"
            :widgetInstanceId="widgetInstanceId"
            :event="fixedEvents[0]"
          />
        </div>
        <div v-else>
          <!-- 历史固定参数 -->
          <div v-for="(fItem, fIndex) in fixedEvents" :key="`f_${fIndex}`">
            <form-card
              v-show="fItem.show !== false"
              :ref="`fixedFormCard_${fIndex}`"
              v-model:item="fixedEvents[fIndex]"
              :is-hidden="isEndTimeHidden"
              :index="fIndex"
              :hide-delete="true"
            />
          </div>
        </div>

        <div v-for="(item, index) in showEvents" :key="index">
          <form-card
            :ref="`showFormCard_${index}`"
            v-model:item="showEvents[index]"
            :is-hidden="isEndTimeHidden"
            :index="index"
            @delete-item="deleteItem"
          />
        </div>
        <slot name="helpInfo"></slot>
      </div>

      <!-- 高级事件联动 -->
      <div v-show="evtType === 'advanced'">
        <AdvanceLinkageEditor :config="config" :widgetInstanceId="widgetInstanceId" />
      </div>

      <!-- 主动触发 -->
      <div v-show="evtType === 'initiative'">
        <LowCodeLinkage ref="lowCodeLikage" :config="config" />
      </div>
    </div>
  </div>
</template>
<script>
import extraConfigEvent from '@/common/extra-config-event.js';
import AdvanceLinkageEditor from '@/components/common/advanced-linkage/advanced-linkage-edtior.vue';
import { isRealTime } from '@/components/common/auto-refresh/auto-refresh-util.js';
import LowCodeLinkage from '@/components/common/low-code/low-code-linkage.vue';
import FormCard from '@/components/panel-linkage-form-card-new/index-xvue.vue';
import LinkageParamsSetting from '@/components/panel-linkage-new/linkage-params-setting.vue';
import { NOT_SUPPORTED_REDIS_LIST, SUPPORT_ADVANCED_EVENT } from '@/utils/constant.js';
import { mapState } from 'vuex';

export default {
  name: 'PanelLinkageNew',
  components: {
    FormCard,
    AdvanceLinkageEditor,
    LinkageParamsSetting,
    LowCodeLinkage,
  },
  props: {
    config: Object,
    widgetInstanceId: String,
    orgConfig: Object,
    canAddEvent: {

      // 是否显示添加事件按钮
      type: Boolean,
      default: true,
    },
  },
  data() {
    return {
      isLoading: false,
      isEndTimeHidden: false,
      form: {
        eventName: '',
        typeAccept: '',
      },
      fixedEvents: [], // 固定事件，用来装发出事件，不可删除
      showEvents: [],
      hideEvents: [],
      evtType: 'normal',
    };
  },
  computed: {
    ...mapState({
      panelConfigs: state => state.VisualComponentsModule.panelConfigs,
    }),

    isRealTime() {
      return isRealTime(this.panelConfigs[this.widgetInstanceId]?.data);
    },

    // 打开了实时通讯开关的组件，不添加接收事件(因为组件接收事件是接收到传入参数之后去主动请求数据)
    canCompAddEvent() {
      if (!this.isRealTime) {
        return this.canAddEvent;
      }
      return false;
    },

    // 是否使用动态添加参数
    isDiyOutSetting() {
      const { propertyPannelName } = this.config;
      if (propertyPannelName) {
        // 试点组件
        const testComps = [
          'vs_card',
          'map_bread_crumb',
          'card_indicator_form',
          'multi_value',
        ];
        const compName = propertyPannelName.replace(`config_${process.env.xvueNameSpace_}`, '');
        return testComps.includes(compName);
      }
      return false;
    },

    // 是否显示高级事件联动
    isAdvancedVisible() {
      if (this.isVisualH5) {
        return false;
      }
      const { propertyPannelName } = this.config;
      if (propertyPannelName) {
        const compName = propertyPannelName.replace(`config_${process.env.xvueNameSpace_}`, '');
        return SUPPORT_ADVANCED_EVENT.includes(compName) || compName.includes('common_map_');
      }
      return true;
    },

    isInitiativeVisible() {
      // 洞察云不显示
      if (window._adoPremise.uc.theme === 'dark') {
        return false;
      }
      return true;
    },

    isShowRedisTip() {
      return !NOT_SUPPORTED_REDIS_LIST.includes(this.config.propertyPannelName);
    },
  },
  watch: {
    config: {
      handler: function(newVal, oldVal) {
        if (newVal.config.property.timeType) {
          const { timeType } = newVal.config.property;
          this.isEndTimeHidden = !timeType.includes('Range') && !timeType.includes('week');
        }
      },
      deep: true,
      immediate: true,
    },
  },
  created() {
    this.initEvents();
  },
  methods: {
    initEvents() {
      // 补充初始化，方便外部直接调用该方法重新展示事件列表
      this.orgEvents = JSON.parse(JSON.stringify(this.config.events));
      this.addExtraEvents();
      this.fixedEvents = [];
      this.showEvents = [];
      this.hideEvents = [];

      this.orgEvents.forEach((eventObj, index) => {
        if (eventObj.type === 'out') {
          this.fixedEvents.push(eventObj);
        } else if (eventObj.show || eventObj.key) {
          eventObj.parameters[0].key = eventObj.parameters[0].key || `key-old-${index}`;

          // eventObj.key 是为了兼容旧的联动组件
          this.showEvents.push(eventObj);
        } else {
          eventObj.parameters[0].key = eventObj.parameters[0].key || `key-old-${index}`;
          this.hideEvents.push(eventObj);
        }
      });
    },

    // 补充事件项
    addExtraEvents() {
      const events = [];
      extraConfigEvent.forEach(n => {
        if (!this.orgEvents.find(n1 => n1.id === n.id)) {
          events.push(JSON.parse(JSON.stringify(n)));
        }
      });
      this.orgEvents = this.orgEvents.concat(events);
    },
    addEvent() {
      if (this.hideEvents.length) {
        const event = this.hideEvents.shift();
        event.show = true;
        this.showEvents.push(event);
      } else {
        this.$message({
          message: this.$demoi18n('message.eventsCountLimited'),
          type: 'warning',
        });
      }
    },
    deleteItem(index) {
      const event = this.showEvents.splice(index, 1);
      event[0].show = false;
      event[0].key = '';
      this.hideEvents.push(event[0]);
    },
    async check(_this) {
      const resValids = [];
      const fixedLen = this.fixedEvents.length;
      const promises = [];
      for (let i = 0; i < fixedLen; i++) {
        const refVm = this.$refs[`fixedFormCard_${i}`];
        if (!refVm) {
          continue;
        }
        const p = this.$refs[`fixedFormCard_${i}`][0].check(_this).then(valid => {
          if (!valid) {
            resValids.push(false);
          }
        });
        promises.push(p);
      }

      const showLen = this.showEvents.length;
      for (let i = 0; i < showLen; i++) {
        const p = this.$refs[`showFormCard_${i}`][0].check(_this).then(valid => {
          if (!valid) {
            resValids.push(false);
          }
        });
        promises.push(p);
      }

      await Promise.all(promises);
      const isFalse = resValids.some(n => n === false);
      const resValid = !isFalse;

      return resValid;
    },
  },
};
</script>
<style lang="less" scoped>
.panel-linkage {
  .content {
    padding: 0 10px;
    .btns_line {
      display: flex;
      justify-content: space-between;
    }
    .btn-add {
      :deep(.el-icon) {
        color: #999;
      }
    }

    .prop-form {
      :deep(.el-form-item) {
        margin-bottom: 0;
      }
    }
  }
}
</style>
